package com.example.demo.common.file.service;


import com.example.demo.common.config.service.ConfigService;
import com.example.demo.common.persistence.dao.SysDocFileMapper;
import com.example.demo.common.persistence.model.SysDocFile;
import com.example.demo.core.util.UserUtil;
import com.example.demo.core.util.WebUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Enumeration;
import java.util.Random;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public abstract class AbstractFileService implements FileService {

    private static Logger logger = LoggerFactory.getLogger(AbstractFileService.class);

    public static String separator = "/";

    @Autowired
    public ConfigService configServiceImpl;

    @Autowired
    public SysDocFileMapper sysDocFileMapper;

    @Override
    public boolean checkDownLoadIp(String ipAddr) {
        return true;
    }

    public String getLocationDir() {

        String locationDir = configServiceImpl.getString("location_dir");

        if (StringUtils.isEmpty(locationDir)) {
            locationDir = System.getProperty("user.home") + separator + ".ebidding/uploadDir";
        } else {
            File tempDir = new File(locationDir);
            if (!tempDir.exists()) {
                locationDir = System.getProperty("user.home") + separator + ".ebidding/uploadDir";
            }
        }

        locationDir = locationDir.replaceAll("\\\\", separator);
        return locationDir;
    }

    public String getTempDir(String modules1, String modules2) {

        String locationTempDir = configServiceImpl.getString("location_temp_dir");

        if (StringUtils.isEmpty(locationTempDir)) {
            locationTempDir = System.getProperty("user.home") + separator + ".ebidding/temp";
        } else {
            File tempDir = new File(locationTempDir);
            if (!tempDir.exists()) {
                locationTempDir = System.getProperty("user.home") + separator + ".ebidding/temp";
            }
        }

        String companyCode = getCompanyCode();
        String dateStr = DateFormatUtils.format(new Date(), "yyyy-MM-dd");

        String dir = locationTempDir + separator;
        dir += companyCode + separator;
        dir += dateStr + separator;
        dir += modules1 + separator;
        dir += modules2 + separator;
        dir += getUUID();
        mkdirs(dir);
        dir = StringUtils.replace(dir, "\\", separator);
        return dir;
    }

    public String getTempFile(String modules1, String modules2, String ext) {

        String locationTempDir = configServiceImpl.getString("location_temp_dir");

        if (StringUtils.isEmpty(locationTempDir)) {
            locationTempDir = System.getProperty("user.home") + separator + ".ebidding/temp";
        } else {
            File tempDir = new File(locationTempDir);
            if (!tempDir.exists()) {
                locationTempDir = System.getProperty("user.home") + separator + ".ebidding/temp";
            }
        }

        String companyCode = getCompanyCode();
        String dateStr = DateFormatUtils.format(new Date(), "yyyy-MM-dd");

        String dir = locationTempDir + separator;
        dir += companyCode + separator;
        dir += dateStr + separator;
        dir += modules1 + separator;
        dir += modules2 + separator;
        mkdirs(dir);

        String fileName = dir += getUUID() + "." + ext;
        fileName = StringUtils.replace(fileName, "\\", separator);
        return fileName;
    }

    public String getUUID() {

        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    public String getCompanyCode() {

        String companyCode = "onelinkplus";
        return companyCode;
    }

    public String createChecksum(InputStream input) {
        return "";
//		try {
//			input.skip(0);
//			ExecTime execTime = new ExecTime();		 
//	
//			byte[] buffer = new byte[1024 * 2];
//			MessageDigest complete = MessageDigest.getInstance("SHA1"); 
//			int numRead;
//	 
//			do {
//				numRead = input.read(buffer);
//				if (numRead > 0) { 
//					complete.update(buffer, 0, numRead);
//				}
//			} while (numRead != -1); 
//				
//			byte[] byteArray = complete.digest();  
//			StringBuffer strBuff = new StringBuffer();  
//	       
//	        for (int i = 0; i < byteArray.length; i++) {              
//	            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)  
//	            	strBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));  
//	            else  
//	            	strBuff.append(Integer.toHexString(0xFF & byteArray[i]));  
//	        }  
//	        
//	        logger.info(execTime.toString());
//	        return strBuff.toString(); 
//		} catch(Exception e) {
//			e.printStackTrace();
//			return "";
//		} finally {
//			IOUtils.closeQuietly(input);
//		}
    }

    public String tenderFile(String filePath) {

        logger.info("文件路径：" + filePath);

        File tenderFile = new File(filePath);
        if (!tenderFile.exists()) return null;

        String zipDir = getTempDir("bkb", "tender");
        logger.info("解压目录：" + zipDir);

        unZipCurrent(tenderFile, zipDir);

        String bidId = "";
        String cfgId = "";
        String rkeyId = "";
        String signId = "";
        String ssigId = "";
        String bid2Id = "";

        File[] files = new File(zipDir).listFiles();
        String fileName = null;
        String fileExt = null;
        if (null != files) {
            for (File file : files) {
                fileName = file.getAbsolutePath();
                logger.info("fileName:" + fileName);
                fileExt = FilenameUtils.getExtension(fileName);
                if (StringUtils.equalsIgnoreCase(fileExt, "bid")) {
                    bidId = putFile(file, "bkb", "tender");
                } else if (StringUtils.equalsIgnoreCase(fileExt, "cfg")) {
                    cfgId = putFile(file, "bkb", "tender");
                } else if (StringUtils.equalsIgnoreCase(fileExt, "rkey")) {
                    rkeyId = putFile(file, "bkb", "tender");
                } else if (StringUtils.equalsIgnoreCase(fileExt, "sign")) {
                    signId = putFile(file, "bkb", "tender");
                } else if (StringUtils.equalsIgnoreCase(fileExt, "ssig")) {
                    ssigId = putFile(file, "bkb", "tender");
                } else if (StringUtils.equalsIgnoreCase(fileExt, "bid2")) {
                    bid2Id = putFile(file, "bkb", "tender");
                }
            }
        }
        //投标文件解压后的文件id，多个逗号分开 bid bid2 sign ssig rkey cfg
        String fileIds = bidId + "," + bid2Id + "," + signId + "," + ssigId + "," + rkeyId + "," + cfgId;

        return fileIds;
    }

    public static void main(String[] args) {

        System.out.println(getRandomChar(8));
    }

    /**
     * JAVA获得0-9,a-z,A-Z范围的随机数
     *
     * @param length 随机数长度
     * @return String
     */
    public static String getRandomChar(int length) {
        char[] chr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        Random random = new Random();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < length; i++) {
            buffer.append(chr[random.nextInt(62)]);
        }
        return buffer.toString();
    }

    public SysDocFile shareFile(String fileId, String expDateStr) {

        SysDocFile docFile = getSysDocFileById(fileId);

        if (StringUtils.isEmpty(docFile.getFileAddress())) {
            Date expDate = null;

            if (StringUtils.isNotEmpty(expDateStr)) {
                try {
                    expDate = DateUtils.parseDate(expDateStr, new String[]{"yyyy-MM-dd HH:mm:ss"});
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            String fileAddress = getRandomChar(10);
            while (true) {
                int countFile = sysDocFileMapper.countByFileAddress(fileAddress);
                if (countFile == 0) break;
            }

            String accessCode = getRandomChar(4);
            SysDocFile update = new SysDocFile();
            update.setId(fileId);
            update.setAccessCode(accessCode);
            update.setExpDate(expDate);
            update.setFileAddress(fileAddress);
            sysDocFileMapper.updateById(update);
            update.setFileAddress(getShareUrl(fileAddress));
            return update;
        } else {

            String fileAddress = docFile.getFileAddress();
            docFile.setFileAddress(getShareUrl(fileAddress));
            return docFile;
        }
    }

    public SysDocFile shareFile(String fileId) {

        SysDocFile docFile = getSysDocFileById(fileId);
        String fileAddress = docFile.getFileAddress();
        docFile.setFileAddress(getShareUrl(fileAddress));
        return docFile;
    }

    public String getShareUrl(String fileAddress) {

        String shareUrl = configServiceImpl.getString("share_url");
        return String.format(shareUrl, fileAddress);
    }

    public void unZipCurrent(String zipfile, String destDir) throws IOException {

        unZipCurrent(new File(zipfile), destDir);
    }

    @SuppressWarnings({"unchecked"})
    public void unZipCurrent(File zipfile, String destDir) {

        destDir = destDir.endsWith("//") ? destDir : destDir + "//";

        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(zipfile, Charset.forName("GB18030"));
            Enumeration<ZipEntry> enumeration = (Enumeration<ZipEntry>) zipFile.entries();
            ZipEntry zipEntry = null;
            while (enumeration.hasMoreElements()) {
                zipEntry = (ZipEntry) enumeration.nextElement();
                File loadFile = new File(destDir + zipEntry.getName());
                if (zipEntry.isDirectory()) {
                    continue;
                } else {
                    OutputStream outputStream = null;
                    InputStream inputStream = null;
                    try {
                        if (!loadFile.getParentFile().exists()) {
                            boolean isMk = loadFile.getParentFile().mkdirs();
                            if (!isMk) {
                                logger.warn("create error");
                            }
                        }

                        outputStream = new FileOutputStream(loadFile);
                        inputStream = zipFile.getInputStream(zipEntry);
                        IOUtils.copy(inputStream, outputStream);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        IOUtils.closeQuietly(outputStream);
                        IOUtils.closeQuietly(inputStream);
                    }

                }
            }
            logger.info(" 文件解压成功 ");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void mkdirs(String dir) {

        File fileDir = new File(dir);
        if (!fileDir.exists()) {
            boolean isMk = fileDir.mkdirs();
            if (!isMk) {
                logger.warn("create error");
            }
        }
    }

    public String getDownloadUrl(String fileId) {

        if (StringUtils.isEmpty(fileId)) return "";

        String downloadUrl = configServiceImpl.getString("download_url");

        downloadUrl += "/" + fileId + ".htm";

        String fileToken = getFileToken();

        String timestamp = String.valueOf((new Date()).getTime());
        String signature = WebUtil.getFileUrlSignature(fileToken, fileId);
        downloadUrl += "?timestamp=" + timestamp + "&signature=" + signature;
        return downloadUrl;
    }

    public String getFileToken() {
        String fileToken = UserUtil.createFileToken();
        String ipAddress = "";
        return fileToken + ipAddress;
    }

    @Override
    public String getDownloadUrlV2(String fileId) {

        if (StringUtils.isEmpty(fileId)) return "";

        String downloadUrl = configServiceImpl.getString("download_url_v2");

        downloadUrl += "/" + fileId + ".htm";
        String timestamp = String.valueOf((new Date()).getTime());
        downloadUrl += "?timestamp=" + timestamp;
        return downloadUrl;
    }

    @Override
    public String getDownLoadParam(String fileId) {
        if (StringUtils.isEmpty(fileId)) return "";


        String downloadUrl = "";

        String fileToken = getFileToken();

        String timestamp = String.valueOf((new Date()).getTime());
        String signature = WebUtil.getFileUrlSignature(fileToken, fileId);
        downloadUrl += "<input name=\"timestamp\" value=\"" + timestamp + "\" id=\"down-timestamp\" type=\"hidden\" />" + "<input name=\"signature\" id=\"down-signature\" value=\"" + signature + "\" type=\"hidden\" />";
        return downloadUrl;
    }

    @Override
    public String getGroupDownLoadParam(String fileId) {
        if (StringUtils.isEmpty(fileId)) return "";


        String downloadUrl = "";

        String fileToken = getFileToken();

        String timestamp = String.valueOf((new Date()).getTime());
        String signature = WebUtil.getFileUrlSignature(fileToken, fileId);
        downloadUrl += "<input name=\"timestamps\" value=\"" + timestamp + "\" id=\"down-timestamp\" type=\"hidden\" />" + "<input name=\"signatures\" id=\"down-signature\" value=\"" + signature + "\" type=\"hidden\" />";
        return downloadUrl;
    }

    protected SysDocFile getSysDocFileByFileId(String fileId) {
        if (StringUtils.isBlank(fileId)) {
            return null;
        }
        SysDocFile sysDocFile = this.sysDocFileMapper.selectById(fileId);

        return sysDocFile;
    }


    @Override
    public String getUploadId(String fileName) {
        return null;
    }

    @Override
    public void multipartUpload(InputStream inputStream, String fileName, String uploadId, long partSize, int partNumber) {

    }

    @Override
    public String completeMultipartUpload(String uploadId, String fileName, String module1, String module2, Long fileSize, String oriFileName, String token) {
        return null;
    }

    @Override
    public String getFileName(String token, String fileName, String module1, String module2) {
        return null;
    }
}

